package sourceagile.server.doclet.java;

import org.codehaus.jettison.json.JSONArray;
import org.codehaus.jettison.json.JSONException;
import org.codehaus.jettison.json.JSONObject;

import com.sun.javadoc.ConstructorDoc;
import com.sun.javadoc.MethodDoc;
import com.sun.javadoc.Parameter;
import com.sun.javadoc.Type;

public class GetClassMethods {

	public static String METHOD_NAME = "method_name";
	public static String METHOD_PARAMETERS = "method_parameters";
	public static String METHOD_DESCRIPTION = "method_description";
	public static String METHOD_RETURN_TYPE = "method_return_type";
	public static String METHOD_MODIFIERS = "method_modifiers";

	/**
	 * List all the methods of a class.
	 */
	public static JSONArray listMethods(MethodDoc[] methodsDoc) {

		JSONArray jsonMethods = new JSONArray();

		for (int i = 0; i < methodsDoc.length; i++) {

			jsonMethods.put(getObjectFromMethodsDoc(methodsDoc[i]));
		}

		return jsonMethods;
	}

	public static JSONArray listConstructors(ConstructorDoc[] constructorDoc) {

		JSONArray jsonMethods = new JSONArray();

		for (int i = 0; i < constructorDoc.length; i++) {

			jsonMethods.put(getObjectFromConstructorDoc(constructorDoc[i]));
		}

		return jsonMethods;
	}

	/**
	 * Convert the parameter list in a String.
	 */
	private static String getParameterString(Parameter[] ps) {

		String result = "";

		for (int i = 0; i < ps.length; i++) {

			Type type = ps[i].type();

			String ename = type.isPrimitive() ? type.typeName() : type
					.asClassDoc().name();

			result += ename + " " + ps[i].name();

			if (i < ps.length - 1) {
				result += ", ";
			}
		}

		return result;
	}

	private static JSONObject getObjectFromConstructorDoc(
			ConstructorDoc constructorDocumentation) {

		JSONObject jsonEntry = new JSONObject();

		try {

			jsonEntry.put(METHOD_NAME, constructorDocumentation.name());
			jsonEntry.put(METHOD_MODIFIERS,
					constructorDocumentation.modifiers());
			jsonEntry.put(METHOD_RETURN_TYPE, "");
			jsonEntry.put(METHOD_PARAMETERS,
					getParameterString(constructorDocumentation.parameters()));
			jsonEntry.put(METHOD_DESCRIPTION,
					constructorDocumentation.commentText());

		} catch (JSONException e) {

			e.printStackTrace();
		}

		return jsonEntry;
	}

	private static JSONObject getObjectFromMethodsDoc(
			MethodDoc methodDocumentation) {

		JSONObject jsonEntry = new JSONObject();

		try {
			jsonEntry.put(METHOD_NAME, methodDocumentation.name());
			jsonEntry.put(METHOD_MODIFIERS, methodDocumentation.modifiers());
			jsonEntry.put(METHOD_RETURN_TYPE, methodDocumentation.returnType()
					.toString());
			jsonEntry.put(METHOD_PARAMETERS,
					getParameterString(methodDocumentation.parameters()));
			jsonEntry
					.put(METHOD_DESCRIPTION, methodDocumentation.commentText());

		} catch (JSONException e) {

			e.printStackTrace();
		}

		return jsonEntry;
	}
}
